package info.qingshui.browser.hk.db;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class ObjectDB {
	private Context mContext = null;

	private ObjectDBHelper mDBHelper = null;

	private SQLiteDatabase objectDatabase = null;

	private static final String DATABASE_NAME = "HKData.db";

	private static final int DATABASE_VERSION = 9;

	public static final String OBJECT_TABLE_NAME = "t_object";
	public static final String CLASS_NAME_COL_NAME = "class_name";
	public static final String CLASS_DATA_COL_NAME = "class_data";

	private static ObjectDB objectDB = null;//单一模式

	// 构造函数，一个引用类的Context作为参数
	private ObjectDB(Context context) {
		mContext = context;
	}
	
	public static synchronized ObjectDB getObjectDB(Context context) {
		if ( objectDB == null ) {
			objectDB = new ObjectDB(context);
		}
		return objectDB;
	}

	// 打开数据库
	private void open() {
		try {
			mDBHelper = new ObjectDBHelper(mContext, DATABASE_NAME, null,
					DATABASE_VERSION);
			objectDatabase = mDBHelper.getWritableDatabase();
			Log.i(this.getClass().getSimpleName(), "open:" + objectDatabase.getPath()); 
		//createObjectTable();
		} catch( Exception e) {
			//this.close();
		}
	}

	// Close the database
	private void close() {
		mDBHelper.close();
	}



	//一操作所有东西就没了
	public void cleanObjectTable() {

		try {
			this.open();
			objectDatabase.delete(OBJECT_TABLE_NAME, null, null);
		} catch (SQLException e) {
			Log.e(this.getClass().getSimpleName(), "cleanObjectTable",e);
		} finally {
			this.close();
		}
		Log.d(this.getClass().getSimpleName(), "cleanObjectTable");
	}

	public boolean saveObject(Object o) {
		Log.d(this.getClass().getSimpleName(), "saveObject ...:" + o);
		boolean r = false;
		try {
			String className = o.getClass().getName();
			String sqlstr = "replace into " + OBJECT_TABLE_NAME
					+ "(" + CLASS_NAME_COL_NAME + "," + CLASS_DATA_COL_NAME + ") values (?,?);";

			Object[] args = new Object[] { className, this.object2Bytes(o) };
			this.open();
			objectDatabase.execSQL(sqlstr, args);
			r = true;
		} catch (SQLException e) {
			Log.e(this.getClass().getSimpleName(), "saveObject error:" + o,e);
		} finally {
			this.close();
		}
		Log.d(this.getClass().getSimpleName(), "saveObject done r=" + r);
		return r;
	}

	public Object getObject(String className) {
		Log.d(this.getClass().getSimpleName(), "getObject ...:className=" + className);
		Object o = null;
		Cursor cur = null;
		byte[] data = null;
		String col[] = { CLASS_NAME_COL_NAME, CLASS_DATA_COL_NAME };
		String selection = CLASS_NAME_COL_NAME + "='" + className + "'";
		try {
			this.open();
			cur = objectDatabase.query(OBJECT_TABLE_NAME, col, selection, null, null,
					null, null);
			if ( cur.moveToFirst()) {
				data = cur.getBlob(1);
				if ( data != null ) {
					o = this.bytes2Object(data);
				}
			}
		} catch (Throwable ex) {
			Log.e(this.getClass().getSimpleName(), "getObject error,className=" + className);
		} finally {
			try {
				if (cur != null)
					cur.close();
				this.close();
			}catch (Throwable ex) {
				Log.w(this.getClass().getSimpleName(), "getObject finally error,className=" + className);
			} 
			
		}
		//Log.d(this.getClass().getSimpleName(), "getObject done,return: " + o);
		return o;

	} 
	
	private  byte[] object2Bytes(Object o) {
		if ( o == null ) {
			return null;
		}
		try {
			ByteArrayOutputStream b = new ByteArrayOutputStream();
			ObjectOutputStream out = new ObjectOutputStream(b);
			out.writeObject(o);
			byte[] ob =  b.toByteArray();
			if ( ob == null || ob.length == 0 ) {
				return null;
			}
			//Log.d(this.getClass().getSimpleName(), "object2Bytes lentgh:" + ob.length);
			return ob;
		} catch (IOException e) {
			Log.e(this.getClass().getSimpleName(), "object2Bytes",e);
			return null;
		}
	}
	
	private  Object bytes2Object(byte[] bts) {
		if ( bts == null || bts.length == 0) {
			return null;
		}
		try {
			//Log.d(this.getClass().getSimpleName(), "bytes2Object length:" + bts.length);
			ByteArrayInputStream i = new ByteArrayInputStream(bts);
			ObjectInputStream in = new ObjectInputStream(i);
			return in.readObject();
		} catch (Exception e) {
			Log.e(this.getClass().getSimpleName(), "bytes2Object",e);
			return null;
		}
	}
	

}
